home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-04-25 | 5.3 KB | 152 lines | [TEXT/3PRM] |
- module CalcDialog
-
- /* A simple desk calculator using a dialog for the calculator.
- This application requires the 0.8 I/O library.
- Run the program using the "No Console" option (Application options).
- */
-
- import StdEnv, deltaEventIO, deltaDialog, deltaFont, deltaPicture
-
- :: State
- = { arg1 :: !String
- , op :: !Operation
- , arg2 :: !String
- }
- :: *IO :== IOState *State
- :: Operation :== Int -> Int -> Int
-
- Start :: *World -> *World
- Start world
- # (events,world) = OpenEvents world
- initstate = {arg1="0",op=K,arg2=""}
- (_,events) = StartIO [DialogSystem [dialog], MenuSystem [menu]] initstate [] events
- world = CloseEvents events world
- = world
- where
- menu :: MenuDef *State IO
- menu = PullDownMenu 0 "File" Able
- [ MenuItem 0 "Open Calculator" (Key 'O') Able Open
- , MenuItem 0 "Quit" (Key 'Q') Able Quit
- ]
- where
- Open :: *State IO -> (*State, IO)
- Open state io = (state, OpenDialog dialog io)
-
- Quit :: *State IO -> (*State, IO)
- Quit state io = (state, QuitIO io)
-
- dialog :: DialogDef *State IO
- dialog = CommandDialog calcId "Calculator"
- [ DialogMargin (Pixel 4) (Pixel 4)
- , ItemSpace (Pixel 4) (Pixel 4)
- ] idEq
- [ DialogIconButton idNum Center NumDom (NumLook "0") Unable (\_ state io -> (state,io))
- , CalcButton id7 (YOffset idNum (Pixel 12)) "7" font (NumBut 7)
- , CalcButton id8 (RightTo id7) "8" font (NumBut 8)
- , CalcButton id9 (RightTo id8) "9" font (NumBut 9)
- , CalcButton idC (RightTo id9) "C" font Clear
- , CalcButton id4 Left "4" font (NumBut 4)
- , CalcButton id5 (RightTo id4) "5" font (NumBut 5)
- , CalcButton id6 (RightTo id5) "6" font (NumBut 6)
- , CalcButton idMul (RightTo id6) "*" font (DiOp (*))
- , CalcButton id1 Left "1" font (NumBut 1)
- , CalcButton id2 (RightTo id1) "2" font (NumBut 2)
- , CalcButton id3 (RightTo id2) "3" font (NumBut 3)
- , CalcButton idMin (RightTo id3) "-" font (DiOp (-))
- , CalcButton id0 Left "0" font (NumBut 0)
- , CalcButton idPlusMin (RightTo id0) "+/-" font PlusMin
- , CalcButton idEq (RightTo idPlusMin) "=" font Becomes
- , CalcButton idPlus (RightTo idEq) "+" font (DiOp (+))
- ]
- where
- calcId = 1
- idNum = 11
- id7 = 7; id8 = 8; id9 = 9; idC = 12
- id4 = 4; id5 = 5; id6 = 6; idMul = 13
- id1 = 1; id2 = 2; id3 = 3; idMin = 18
- id0 = 10; idPlusMin = 15; idEq = 14; idPlus = 19
-
- (_,font)= SelectFont "Geneva" [] 9
-
- CalcButton :: DialogItemId ItemPos ItemTitle Font (ButtonFunction *State IO) -> DialogItem *State IO
- CalcButton id pos title font bfunc
- = DialogIconButton id pos buttonDomain look Able bfunc
- where
- buttonWidth = 28
- buttonHeight= 16
- buttonDomain= ((0,0),(buttonWidth,buttonHeight))
-
- look :: SelectState -> [DrawFunction]
- look _
- = [ SetFont font
- , FillRectangle shadowrect
- , SetPenColour (RGB 0.5 0.5 0.5)
- , FillRectangle buttonrect
- , SetPenColour BlackColour
- , DrawRectangle buttonrect
- , MovePenTo ((buttonWidth-FontStringWidth title font)/2-1,11)
- , SetPenMode OrMode
- , DrawString title
- ]
- where
- shadowrect = ((2,2),(buttonWidth,buttonHeight))
- buttonrect = ((0,0),(buttonWidth-2,buttonHeight-2))
-
- NumBut :: Int DialogInfo *State IO -> (*State, IO) // The button function for the 0,1,2...9 buttons
- NumBut num dialog state=:{arg1, arg2} io
- | arg2=="" = ({state & arg1=num1}, ChangeNumber num1 io)
- with
- num1 = addDigit arg1 num
- | otherwise = ({state & arg2=num2}, ChangeNumber num2 io)
- with
- num2 = addDigit arg2 num
- where
- addDigit :: !String !Int -> String
- addDigit arg nr
- | size arg>=12 = arg
- | arg=="0" = toString nr
- | otherwise = arg+++toString nr
-
- Clear :: DialogInfo *State IO -> (*State, IO) // The button function for the Clear button
- Clear _ _ io = ({arg1="0",op=K,arg2=""}, ChangeNumber "0" io)
-
- DiOp :: Operation DialogInfo *State IO -> (*State, IO) // The button function for the '*','-', and '+' button
- DiOp operator dialog state=:{arg2} io
- | arg2=="" = ({state & op=operator,arg2="0"}, io)
- | otherwise = (state, Beep io)
-
- PlusMin :: DialogInfo *State IO -> (*State, IO) // The button function for the '+/-' button
- PlusMin dialog state=:{arg1, arg2} io
- | arg2=="" = ({state & arg1=neg1}, ChangeNumber neg1 io)
- with
- neg1 = ~arg1
- | otherwise = ({state & arg2=neg2}, ChangeNumber neg2 io)
- with
- neg2 = ~arg2
-
- Becomes :: DialogInfo *State IO -> (*State, IO) // The button function for the '=' button
- Becomes dialog {arg1,op,arg2} io
- = ({arg1=result,op=K,arg2=""}, ChangeNumber result io)
- where
- result = toString (op (toInt arg1) (toInt arg2))
-
- NumDom = ((0,0),(105,17))
-
- NumLook :: String SelectState -> [DrawFunction] // The look of the calculator display
- NumLook num _
- = [ MovePenTo (4,13)
- , SetPenColour BlackColour
- , SetPenMode OrMode
- , DrawString num
- , SetPenNormal
- , DrawRectangle NumDom
- ]
-
- ChangeNumber :: String IO -> IO // Change the number in the calculator display
- ChangeNumber num io = ChangeDialog calcId [ChangeIconLook idNum (NumLook num)] io
-
- instance ~ {#Char}
- where
- (~) :: !{#Char} -> {#Char}
- (~) numstring = toString (~(toInt numstring))
-